<template>
  <el-input v-model="str" @input="checkValid" />
  <span v-if="str.length">{{ res }}</span>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const str = ref<string>('')
const res = ref<boolean>(false)
const checkValid = (str: string) => {
  res.value = checkString(str)
}

function checkString(str:string) {
  if (str.search(/[^\{\}\[\]\(\)]+/) > -1) {
    return false
  }
  const arr1:number[] = []
  const arr2:number[] = []
  const arr3:number[] = []
  const arr4:number[] = []
  const arr5:number[] = []
  const arr6:number[] = []
  for (let i = 0; i < str.length; i++) {
    switch (str[i]) {
      case '{':
        arr1.push(i)
        break
      case '}':
        arr2.push(i)
        break
      case '[':
        arr3.push(i)
        break
      case ']':
        arr4.push(i)
        break
      case '(':
        arr5.push(i)
        break
      case ')':
        arr6.push(i)
        break
    }
  }
  return [[arr1, arr2], [arr3, arr4], [arr5, arr6]].every((item, index) => checkOne(item, str, index))
}
type Basic=[number, number]
function checkOne(arr: number[][], str:string, index:number) {
  const [left, right] = arr
  if (left.length !== right.length) {
    return false
  }
  const mid:Basic[] = []
  right.forEach(item => {
    const itemBrother = left.reduce((res, sub) => sub < item ? sub : res, -1)
    if (itemBrother !== -1) {
      left.splice(left.indexOf(itemBrother), 1)
      mid.push([itemBrother, item])
    }
  })
  if (mid.length < right.length) {
    return false
  } else {
    const isEven = mid.every(item => (item[1] - item[0]) % 2 === 1)
    if (!isEven) {
      return false
    } else {
      return checkChild(mid, str, index)
    }
  }
}
function checkChild(arrs:Basic[], str:string, index:number) {
  if (index === 0) { return true }
  let inValid: string
  switch (index) {
    case 1:
      inValid = '[\{]+'
      break
    case 2:
      inValid = '[\{\[]+'
      break
  }
  return arrs.every(item => {
    const mid = str.slice(item[0] + 1, item[1])
    const subIndex = mid.search(new RegExp(inValid))
    return subIndex === -1
  })
}
</script>
